<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">
    <link rel="stylesheet" href="./assets/fontawesome/css/all.min.css">

    <style>
        .map-container {
            background-image: url('./assets/monopoly/map.jpg');
            width: 1225px;
            height: 837px;
            position: relative;
        }

        .map-element {
            position: absolute;
            z-index: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-wrap: wrap;
        }

        .map-element .player {
            width: 36px;
            height: 36px;
            margin-right: 5px;
            border-radius: 50%;
            background-repeat: no-repeat;
            background-size: contain;
            border: 4px solid var(--border-color);
            z-index: 1;
        }

        .map-element .corona {
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            top: 0;
            pointer-events: none;
            border: 4px solid var(--border-color);
        }

        .map-element .corona i {
            opacity: 0;
            padding: 5px;
        }

        .map-element .corona .mortgaged {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) rotate(30deg) scale(1.4);
            font-weight: bold;
            text-shadow: 2px 2px red;
        }

        .map-element .corona[level='1'] i:nth-of-type(1) {
            opacity: 1;
            color: green;
        }

        .map-element .corona[level='2'] i {
            opacity: 1;
            color: green;
        }

        .map-element .corona[level='3'] i:nth-of-type(1) {
            opacity: 1;
            color: red;
        }

        .map-mask,
        .commentary-seat {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(255, 255, 255, .8);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 2;
        }

        .map-mask .game-start .players {
            display: flex;
        }

        .map-mask .game-start .player {
            margin-left: 20px;
            text-align: center;
            padding: 20px;
            background: #fff;
            user-select: none;
        }

        .map-mask .game-start .player.active {
            background: #caf09f;
        }

        .map-mask .game-start .player img {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            pointer-events: none;
        }

        .game-start .btns {
            display: flex;
        }

        .game-start .start-btn,
        .game-start .rule-btn {
            padding: 10px 20px;
            margin: 20px auto;
            background-color: #70d1cc;
            user-select: none;
        }

        [class$='-btn'] {
            user-select: none;
        }

        [class$='-btn']:active {
            opacity: .7;
        }

        .game-rule {
            position: relative;
        }

        .game-rule .fa-times {
            position: absolute;
            right: 0;
            width: 100px;
            height: 100px;
            font-size: 30px;
            color: #f57373;
            text-align: center;
            line-height: 100px;
        }

        .commentary-seat {
            display: none;
            left: 171px;
            top: 171px;
            right: 171px;
            bottom: 171px;
            justify-content: start;
            align-items: start;
        }

        .commentary-seat .player-list {
            display: flex;
            flex-direction: column;
            padding-top: 20px;
            padding-left: 20px;
        }

        .commentary-seat .player-list .player {
            display: flex;
            margin-bottom: 20px;
            position: relative;
        }

        .commentary-seat .player .avatar {
            width: 50px;
            height: 50px;
            border-radius: 50%;
        }

        .commentary-seat .player .fund {
            display: flex;
            align-items: center;
            padding-left: 10px;
            font-weight: bold;
            color: black;
            text-shadow: 2px 2px gold;
        }

        .commentary-seat .inventory {
            display: flex;
            align-items: center;
        }

        .commentary-seat .player .bankruptcy {
            position: absolute;
            left: 0;
            top: 0;
            background-color: rgba(59, 59, 59, 0.5);
            border-radius: 50%;
            height: 100%;
            width: 50px;
            color: #f24;
            text-align: center;
            line-height: 50px;
            font-size: 14px;
            font-weight: bold;
            transform: rotate(30deg);
        }

        .commentary-seat .player .card {
            margin-left: 10px;
            background: var(--bg-color);
            padding: 5px 5px;
            border: 1px solid #ddd;
        }

        .commentary-seat .player .avatar.active {
            border: 4px solid var(--border-color);
            box-sizing: border-box;
        }

        .commentary-seat .dice {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }

        .commentary-seat .dice img {
            pointer-events: none;
        }

        .commentary-seat .log-list {
            position: absolute;
            left: 0;
            bottom: 0;
            max-height: 180px;
            width: 300px;
            padding-left: 20px;
            padding-bottom: 20px;
            overflow-y: auto;
        }

        .chance-container,
        .destiny-container,
        .business-container,
        .destiny-select,
        .pause-user-select,
        .game-over-container,
        .bank-container {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(255, 255, 255, .8);
        }

        .game-over-container {
            padding-top: 150px;
            text-align: center;
            font-weight: 700;
            font-size: 30px;
        }

        .game-over-container .reset-btn {
            padding: 10px 20px;
            background-color: #44a0c4;
            width: 200px;
            margin: 80px auto 0;
            font-size: 20px;
            color: #fff;
        }

        .chance-container .result,
        .destiny-container .result {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
        }

        .chance-container .loading,
        .destiny-container .loading {
            width: 100%;
            height: 100%;
            transform: rotateY(0deg);
            animation-name: rotating;
            animation-duration: 1s;
            animation-iteration-count: infinite;
        }

        .pause-user-select {
            padding: 100px 0;
            text-align: center;
            vertical-align: middle;
        }

        .pause-user-select .select-btn {
            display: inline-block;
            width: 120px;
            height: 120px;
            border: 2px solid #ddd;
            margin-right: 20px;
            user-select: none;
        }

        .pause-user-select .select-btn:active {
            background-color: #caf09f;
        }

        .pause-user-select .select-btn img {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            padding-top: 20px;
        }

        .chance-container img,
        .destiny-container img {
            position: absolute;
            left: 50%;
            top: 50%;
            height: 442px;
            width: 248px;
            transform: translate(-50%, -50%) rotate(90deg);
        }

        .destiny-select .select-btn:first-child {
            position: absolute;
            left: 30%;
            top: 50%;
            height: 100%;
        }

        .destiny-select .select-btn:last-child {
            position: absolute;
            left: 70%;
            top: 50%;
            height: 100%;
        }

        .destiny-select img {
            height: 221px;
            width: 124px;
            transform: translate(-50%, -50%) rotate(90deg);
        }

        .chance-container .result-close-btn,
        .destiny-container .result-close-btn {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 50%;
            top: 400px;
            background: #f24;
            transform: translateX(-50%);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 28px;
            color: #fff;
        }

        .business-container {
            white-space: nowrap;
            display: flex;
            width: 100%;
        }

        .business-container .info,
        .business-container .operate {
            display: flex;
        }

        .business-container .info {
            padding: 20px;
            margin-left: 300px;
        }

        .business-container .operate {
            flex-direction: column;
            padding-top: 100px;
            flex: 1;
        }

        .business-container .operate .h2 {
            font-size: 28px;
            font-weight: bold;
            color: #555;
            text-align: center;
        }

        .business-container .info img {
            width: 250px;
            height: 426px;
        }

        .business-container .buy-land-btn,
        .business-container .buy-house-btn,
        .business-container .buy-hotel-btn,
        .business-container .free-buy-house-btn,
        .business-container .pass-btn,
        .business-container .redeem-btn {
            padding: 10px 20px;
            background-color: #44a0c4;
            width: 200px;
            margin: 20px auto 0;
        }

        .pass-btn {
            background-color: #949494;
        }

        .bank-container h2 {
            text-align: center;
        }

        .bank-container .desc {
            padding: 0 100px;
        }

        .bank-container .land-list {
            max-height: 270px;
            overflow: auto;
            margin: 20px 100px;
            padding: 0px;
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
        }

        .bank-container .land-item {
            position: relative;
            margin-bottom: 20px;
            display: flex;
            width: 48%;
            box-sizing: border-box;
            background-color: #e4e3e3;
        }

        .bank-container .land-item .info {
            display: flex;
            align-items: center;
            flex: 1;
            justify-content: space-between;
            padding: 20px;
        }

        .bank-container .land-item .mortgaged {
            position: absolute;
            background-color: rgb(233, 162, 9);
            font-size: 14px;
            left: 0;
            top: 0;
        }

        .bank-container .land-item .mortgage-btn {
            background-color: #44a0c4;
            width: 60px;
            line-height: 60px;
            text-align: center;
        }

        .bank-container .cancel-btn {
            position: absolute;
            right: 100px;
            bottom: 20px;
            background-color: #44a0c4;
            width: 200px;
            padding: 10px 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }


        @keyframes rotating {
            0% {
                transform: rotateY(0deg);

            }

            50% {
                transform: rotateY(180deg);
            }

            100% {
                transform: rotateY(0deg);

            }
        }
    </style>
</head>

<body>
    <div class="map-container">
        <div class="map-mask">
            <div class="game-start">
                <div class="players select">
                    <div class="player active">
                        <img src="./assets/monopoly/black.jpg" alt="小黑">
                        <div class="name">小黑</div>
                        <div class="color" hidden>black</div>
                    </div>
                    <div class="player active">
                        <img src="./assets/monopoly/red.jpg" alt="小红">
                        <div class="name">小红</div>
                        <div class="color" hidden>red</div>
                    </div>
                    <div class="player">
                        <img src="./assets/monopoly/yellow.jpg" alt="小黄">
                        <div class="name">小黄</div>
                        <div class="color" hidden>yellow</div>
                    </div>
                    <div class="player">
                        <img src="./assets/monopoly/blue.jpg" alt="小蓝">
                        <div class="name">小蓝</div>
                        <div class="color" hidden>blue</div>
                    </div>
                </div>
                <div class="btns">
                    <div class="start-btn">开始游戏</div>
                    <div class="rule-btn">规则查看</div>
                </div>
            </div>
            <div class="game-rule" hidden>
                <img src="./assets/monopoly/rule.jpg" alt="游戏规则">
                <i class="fas fa-times rule-close-btn"></i>
            </div>
        </div>
        <div class="commentary-seat">
            <div class="player-list"> </div>
            <div class="dice">
                <img src="./assets/monopoly/1.png" alt="1">
                <img src="./assets/monopoly/2.png" alt="2" hidden>
                <img src="./assets/monopoly/3.png" alt="3" hidden>
                <img src="./assets/monopoly/4.png" alt="4" hidden>
                <img src="./assets/monopoly/5.png" alt="5" hidden>
                <img src="./assets/monopoly/6.png" alt="6" hidden>
            </div>
            <div class="log-list"></div>
            <div class="chance-container" hidden>
                <div class="loading">
                    <img src="./assets/monopoly/chance.jpg">
                </div>
                <div class="result" hidden>
                    <img src="./assets/monopoly/chance.jpg">
                    <div class="result-close-btn">
                        <i class="fas fa-times"></i>
                    </div>
                </div>
            </div>
            <div class="destiny-container" hidden>
                <div class="loading">
                    <img src="./assets/monopoly/destiny.jpg">
                </div>
                <div class="result" hidden>
                    <img src="./assets/monopoly/destiny.jpg">
                    <div class="result-close-btn">
                        <i class="fas fa-times"></i>
                    </div>
                </div>
            </div>
            <div class="business-container" style="display: none;">
                <div class="info">
                    <img src="./assets/monopoly/land1.jpg" alt="地产">
                </div>
                <div class="operate">
                    <div class="h2">请选择您的操作</div>
                    <div class="buy-land-btn">购买土地</div>
                    <div class="buy-house-btn">购买房子</div>
                    <div class="free-buy-house-btn">免费升级</div>
                    <div class="redeem-btn">赎回</div>
                    <div class="pass-btn">路过</div>
                </div>
            </div>
            <div class="destiny-select" hidden>
                <div class="select-btn chance">
                    <img src="./assets/monopoly/chance.jpg">
                </div>
                <div class="select-btn destiny">
                    <img src="./assets/monopoly/destiny.jpg">
                </div>
            </div>
            <div class="pause-user-select" hidden></div>

            <div class="bank-container" hidden>
                <h2>银行</h2>
                <div class="desc">
                    我们是一个很公正的机构哦😀~ 您已经没有💴票子啦，需要抵押一些土地(赎回时收取10%的手续费💴)，不然您就要被淘汰喽
                </div>
                <div class="land-list">
                    <div class="land-item">
                        <div class="info">
                            <div class="name">加拿大</div>
                            <div class="money">2600元</div>
                        </div>
                        <div class="mortgage-btn">抵押</div>
                        <div class="mortgaged">已抵押</div>
                    </div>
                </div>
                <div class="cancel-btn">放弃抵押(游戏结束)</div>
            </div>

            <div class="game-over-container" hidden>
                <div class="h1">恭喜小红获得游戏胜利</div>
                <div class="reset-btn">重新开始</div>
            </div>
        </div>
    </div>

    <script type="module">
        // 默认地图事件
        class MapFunction {
            constructor({
                pass,
                stop
            } = {}) {
                this.pass = pass ?? function (player, score) {
                    console.log('经过', player, score);
                }
                this.stop = stop ?? function (player, score) {
                    console.log('停留', player, score);
                }
            }
        }
        // 地图土地事件
        class MapLandFunction extends MapFunction {
            constructor({
                id,
                landSrc,
                pass,
                stop,
                toll,
                money,
                holder,
                upgrade,
                level,
                maxLevel,
                name,
                mortgaged
            } = {}) {
                super({ pass, stop });
                this.landSrc = landSrc ?? ''
                this.toll = toll
                this.money = money
                this.holder = holder
                this.upgrade = upgrade
                this.level = level
                this.maxLevel = maxLevel
                this.name = name
                this.id = id
                this.mortgaged = mortgaged
                let corona = document.createElement('div')
                let mortgagedDom = document.createElement('div')

                corona.classList.add('corona')
                mortgagedDom.hidden = true
                mortgagedDom.textContent = '已抵押'
                mortgagedDom.classList.add('mortgaged')
                corona.appendChild(mortgagedDom)
                Object.defineProperty(this, 'mortgaged', {
                    get() {
                        return mortgaged
                    },
                    set(val) {
                        if (val) {
                            log(`玩家${holder.name} 将${name}的土地使用权抵押给银行`)
                            mortgagedDom.hidden = false
                        }
                        else {
                            log(`玩家${holder.name} 将${name}的土地使用权赎回`)
                            mortgagedDom.hidden = true
                        }
                        mortgaged = val
                    }
                })


                Object.defineProperty(this, 'holder', {
                    get() {
                        return holder
                    },
                    set(val) {
                        if (val !== null) {
                            log(`玩家${val.name} 购买了${name}的土地使用权 花费${money}元`)
                            corona.setAttribute('style', `--border-color:${val.color}`)
                            for (let i = 0; i < 2; i++) {
                                let house = document.createElement('i')
                                house.classList.add('fas', 'fa-home')
                                corona.appendChild(house)
                            }
                            mapElementList[id].appendChild(corona)
                        }
                        else {
                            corona.remove()
                        }
                        holder = val
                    }
                })

                Object.defineProperty(this, 'level', {
                    get() {
                        return level
                    },
                    set(val) {
                        if (val !== 0) {
                            log(`玩家${holder.name} 在${name}土地升级了房屋`)
                            // 俩绿 一红
                            corona.setAttribute('level', val)
                        }
                        level = val
                    }
                })

            }
        }
        // 机会事件
        class ChanceFunction {
            constructor({
                name,
                /** 信息 */
                info,
                /** 奖罚 */
                award,
                /** 结果图 */
                resultSrc,
                /** 结果事件 */
                resultFunc,
                /** 关闭事件 */
                closeFunc
            } = {}) {
                this.name = name ?? ''
                this.info = info ?? ''
                this.award = award ?? ''
                this.resultSrc = resultSrc ?? ''
                this.resultFunc = resultFunc ?? function () { }
                this.closeFunc = closeFunc ?? function () { }
                this.container = document.querySelector('.chance-container');
                this.loading = this.container.querySelector('.loading')
                this.result = this.container.querySelector('.result')
                this.closeBtn = this.result.querySelector('.result-close-btn')
                this.closeBtn.addEventListener('click', () => {
                    this.container.hidden = true;
                    this.closeFunc()
                })
                let that = this;
                this.run = function (player) {
                    this.container.hidden = false;
                    this.result.hidden = true;
                    setTimeout(() => {
                        this.resultFunc.bind(that, player)()
                        this.result.querySelector('img').src = this.resultSrc
                        this.result.hidden = false;
                    }, 1500)
                }
            }

        }
        // 命运事件
        class DestinyFunction {
            constructor({
                name,
                /** 信息 */
                info,
                /** 奖罚 */
                award,
                /** 结果图 */
                resultSrc,
                /** 结果事件 */
                resultFunc,
                /** 关闭事件 */
                closeFunc
            } = {}) {
                this.name = name ?? ''
                this.info = info ?? ''
                this.award = award ?? ''
                this.resultSrc = resultSrc ?? ''
                this.resultFunc = resultFunc ?? function () { }
                this.closeFunc = closeFunc ?? function () { }
                this.container = document.querySelector('.destiny-container');
                this.loading = this.container.querySelector('.loading')
                this.result = this.container.querySelector('.result')
                this.closeBtn = this.result.querySelector('.result-close-btn')
                this.closeBtn.addEventListener('click', () => {
                    this.container.hidden = true;
                    this.closeFunc()
                })
                let that = this;
                this.run = function (player) {
                    this.container.hidden = false;
                    this.result.hidden = true;
                    setTimeout(() => {
                        this.resultFunc.bind(that, player)()
                        this.result.querySelector('img').src = this.resultSrc
                        this.result.hidden = false;
                    }, 1500)
                }
            }
        }
        // 玩家背包
        class Knapsack extends Array {
            constructor(player) {
                super()
                this.player = player
            }
            push(...items) {
                super.push(...items)
                this.render(...items)
            }
            splice(start, deleteCount, ...items) {
                let inventory = this.player.inventory
                let deleteList = this.slice(start - 1, start + deleteCount);
                for (let i = 0; i < deleteList.length; i++) {
                    const element = deleteList[i];
                    console.log(inventory.querySelector(`.card[title=${element.name}]`));
                    inventory.querySelector(`.card[title=${element.name}]`).remove()
                }
                super.splice(start, deleteCount, ...items)
                this.render(...items)
            }
            render(...items) {
                let inventory = this.player.inventory
                for (let i = 0; i < items.length; i++) {
                    const name = items[i].name;
                    let card = document.createElement('div')
                    card.classList.add('card')
                    card.textContent = name[0]
                    card.setAttribute('title', name)
                    switch (name) {
                        case "出狱许可证":
                            card.setAttribute('style', `--bg-color:rgb(242,199,6)`)
                            break;
                        case "免费升级卡":
                            card.setAttribute('style', `--bg-color:rgb(206,54,43)`)
                            break;
                    }
                    inventory.appendChild(card)
                }
            }
        }
        // 三方库  仅使用随机模块
        import { Randoms } from "https://gcore.jsdelivr.net/npm/@3r/tool/lib/randoms.js";

        // 配置
        const config = {
            // 初始资金
            money: 5000, // (5000 + 2000 + 1000 + 500 + 200 + 100) * 2
            // 手续费 + 本金
            commission: 1.1
        }

        // 地图容器
        let mapContainer = document.querySelector('.map-container')
        // 地图遮罩
        let mapMask = document.querySelector('.map-mask')
        // 开始游戏
        let gameStart = document.querySelector('.game-start')
        // 观众席
        let commentarySeat = document.querySelector('.commentary-seat')
        // 游戏规则
        let gameRule = document.querySelector('.game-rule')
        // 规则按钮
        let ruleBtn = document.querySelector('.rule-btn')
        // 开始按钮
        let startBtn = document.querySelector('.start-btn')
        // 规则关闭按钮
        let ruleCloseBtn = document.querySelector('.rule-close-btn')
        // 开始游戏前选择玩家
        let selectPlayers = document.querySelectorAll('.players.select .player')
        // 🎲
        let dice = commentarySeat.querySelector('.dice')
        // 日志
        let logList = commentarySeat.querySelector('.log-list')

        // 玩家信息列表
        let playerInfoList = []
        // 地图元素列表
        let mapElementList = []
        // 地图方法列表
        let mapFunctionList = []
        // 机会事件列表
        let chanceFunctionList = []
        // 命运事件列表
        let destinyFunctionList = []
        // 🎲是否转动中
        let diceTurn = false;
        // 🙋‍哪位玩家操作
        let dicePlayerIndex = 0

        // 初始化
        function init() {
            // 标记地图元素信息列表
            let mapElementInfoList = [
                {
                    top: '667px',
                    left: '1056px',
                    width: '169px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '945px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '834px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '723px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '612px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '501px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '390px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '279px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '168px',
                    width: '109px',
                    height: '167px',
                },
                {
                    top: '667px',
                    left: '0',
                    width: '166px',
                    height: '167px',
                },
                {
                    top: '568px',
                    left: '0',
                    width: '168px',
                    height: '96px'
                },
                {
                    top: '469px',
                    left: '0',
                    width: '168px',
                    height: '96px'
                },
                {
                    top: '370px',
                    left: '0',
                    width: '168px',
                    height: '96px'
                },
                {
                    top: '272px',
                    left: '0',
                    width: '168px',
                    height: '96px'
                },
                {
                    top: '173px',
                    left: '0',
                    width: '168px',
                    height: '96px'
                },
                {
                    top: '0px',
                    left: '0',
                    width: '171px',
                    height: '171px',
                },
                {
                    top: '7px',
                    left: '173px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '284px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '394px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '505px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '615px',
                    width: '105px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '723px',
                    width: '107px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '832px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '7px',
                    left: '943px',
                    width: '109px',
                    height: '166px',
                },
                {
                    top: '6px',
                    left: '1054px',
                    width: '170px',
                    height: '166px',
                },
                {
                    top: '175px',
                    left: '1054px',
                    width: '170px',
                    height: '98px',
                },
                {
                    top: '275px',
                    left: '1054px',
                    width: '170px',
                    height: '93px',
                },
                {
                    top: '370px',
                    left: '1054px',
                    width: '170px',
                    height: '98px',
                },
                {
                    top: '470px',
                    left: '1054px',
                    width: '170px',
                    height: '95px',
                },
                {
                    top: '567px',
                    left: '1054px',
                    width: '170px',
                    height: '98px',
                },
            ]
            for (let i = 0; i < mapElementInfoList.length; i++) {
                const info = mapElementInfoList[i]
                const element = document.createElement('div')
                element.setAttribute('style', `top:${info.top};left:${info.left};width:${info.width};height:${info.height}`)
                element.classList.add('map-element')
                // 储存列表中
                mapElementList.push(element)
                // 塞入页面渲染
                mapContainer.appendChild(element)

            }


            // 交易容器
            let businessContainer = document.querySelector('.business-container');

            // 交易页面路过操作
            let businessContainerPassBtn = businessContainer.querySelector('.pass-btn');
            businessContainerPassBtn.addEventListener("click", () => {
                businessContainer.setAttribute('style', 'display:none')
                nextDicePlayer()
            })

            // 当前交易的地皮
            let currentBusinessLand = null
            // 购买地皮
            let businessContainerBuyLandBtn = businessContainer.querySelector('.buy-land-btn');
            businessContainerBuyLandBtn.addEventListener('click', () => {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                if (currentPlayer.money < currentBusinessLand.money) {
                    alert('余额不足无法购买')
                }
                else {
                    currentPlayer.money -= currentBusinessLand.money;
                    currentBusinessLand.holder = currentPlayer;
                    businessContainer.setAttribute('style', 'display:none')
                    nextDicePlayer()
                }
            })
            // 买🏠
            let businessContainerBuyHouseBtn = businessContainer.querySelector('.buy-house-btn');
            businessContainerBuyHouseBtn.addEventListener('click', () => {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                if (currentPlayer.money < currentBusinessLand.upgrade) {
                    alert('余额不足无法升级')
                }
                else {
                    currentPlayer.money -= currentBusinessLand.upgrade;
                    currentBusinessLand.level++;
                    businessContainer.setAttribute('style', 'display:none')
                    nextDicePlayer()
                }
            })
            // 0元购🏠
            let businessContainerFreeBuyHouseBtn = businessContainer.querySelector('.free-buy-house-btn')
            businessContainerFreeBuyHouseBtn.addEventListener('click', () => {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                let idx = currentPlayer.knapsack.findIndex(item => item.name === '免费升级卡')
                currentPlayer.knapsack.splice(idx, 1)
                currentBusinessLand.level++;
                businessContainer.setAttribute('style', 'display:none')
                nextDicePlayer()
            })
            // 赎回 
            let businessContainerRedeemBtn = businessContainer.querySelector('.redeem-btn')
            businessContainerRedeemBtn.addEventListener('click', () => {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                let levelMoney = currentBusinessLand.level * currentBusinessLand.upgrade
                let totalMoney = currentBusinessLand.money + (isNaN(levelMoney) ? 0 : levelMoney)
                totalMoney = ~~(totalMoney * config.commission)
                if (currentPlayer.money < totalMoney) {
                    alert('余额不足无法赎回')
                }
                else {
                    businessContainer.setAttribute('style', 'display:none')
                    currentBusinessLand.mortgaged = false
                    nextDicePlayer()
                }
            })

            // 在国家止步
            let countryStop = function (player, score) {
                let img = businessContainer.querySelector('.info img')
                img.src = this.landSrc;
                businessContainerBuyLandBtn.hidden = true;
                businessContainerBuyHouseBtn.hidden = true;
                businessContainerFreeBuyHouseBtn.hidden = true;
                businessContainerRedeemBtn.hidden = true;
                if (!this.holder || this.holder === player) {
                    currentBusinessLand = this;
                    if (this.mortgaged) {
                        console.log(currentBusinessLand);
                        businessContainerRedeemBtn.hidden = false;
                        let levelMoney = currentBusinessLand.level * currentBusinessLand.upgrade
                        let totalMoney = currentBusinessLand.money + (isNaN(levelMoney) ? 0 : levelMoney)
                        totalMoney = ~~(totalMoney * config.commission)
                        businessContainerRedeemBtn.textContent = `赎回土地(${totalMoney}元)`
                    }
                    else if (this.level === 3) {
                        nextDicePlayer()
                    }
                    else if (this.holder === player) {
                        let upgradeText = this.level === 2 ? '升级旅馆' : '购买房屋'
                        let idx = player.knapsack.findIndex(item => item.name === '免费升级卡')
                        if (idx > -1) {
                            businessContainerFreeBuyHouseBtn.hidden = false;
                        }
                        log(`玩家${player.name} 在${this.name}土地${upgradeText}`)
                        businessContainerBuyHouseBtn.textContent = `${upgradeText}(${this.upgrade}元)`
                        businessContainerBuyHouseBtn.hidden = false;
                    }
                    else {
                        businessContainerBuyLandBtn.textContent = `购买土地(${this.money}元)`
                        businessContainerBuyLandBtn.hidden = false;
                    }
                    if (this.level < 3) businessContainer.setAttribute('style', 'display:flex')
                }
                else if (!this.mortgaged) {
                    let toll = this.toll[this.level]
                    player.money -= toll;
                    this.holder.money += toll
                    log(`玩家${player.name}停留${this.name} 给玩家${this.holder.name} 支付过路费${toll}元`)
                    nextDicePlayer()
                }
                else {
                    nextDicePlayer()
                }
            }
            // 在水电厂止步
            let hydropowerStop = function (player, score) {
                let img = businessContainer.querySelector('.info img')
                img.src = this.landSrc;
                businessContainerBuyLandBtn.hidden = true;
                businessContainerBuyHouseBtn.hidden = true;
                businessContainerFreeBuyHouseBtn.hidden = true;
                businessContainerRedeemBtn.hidden = true;

                if (this.mortgaged) {
                    businessContainerRedeemBtn.hidden = false;
                    let totalMoney = currentBusinessLand.money
                    totalMoney = ~~(totalMoney * config.commission)
                    businessContainerRedeemBtn.textContent = `赎回土地(${totalMoney}元)`
                }
                else if (!this.holder) {
                    currentBusinessLand = this;
                    businessContainerBuyLandBtn.textContent = `购买土地(${this.money}元)`
                    businessContainerBuyLandBtn.hidden = false;
                    businessContainer.setAttribute('style', 'display:flex')
                }
                else if (this.holder === player) {
                    nextDicePlayer()
                }
                else if (!this.mortgaged) {
                    let level = mapFunctionList[5].holder === mapFunctionList[28].holder ? 1 : 0
                    let toll = this.toll[level] * score
                    player.money -= toll;
                    this.holder.money += toll
                    log(`玩家${player.name}停留${this.name} 给玩家${this.holder.name} 支付过路费${toll}元`)
                    nextDicePlayer()
                }
                else {
                    nextDicePlayer()
                }
            }
            // 在机场止步
            let airfieldStop = function (player, score) {
                let img = businessContainer.querySelector('.info img')
                img.src = this.landSrc;
                businessContainerBuyLandBtn.hidden = true;
                businessContainerBuyHouseBtn.hidden = true;
                businessContainerFreeBuyHouseBtn.hidden = true;
                businessContainerRedeemBtn.hidden = true;
                if (this.mortgaged) {
                    businessContainerRedeemBtn.hidden = false;
                    let totalMoney = currentBusinessLand.money
                    totalMoney = ~~(totalMoney * config.commission)
                    businessContainerRedeemBtn.textContent = `赎回土地(${totalMoney}元)`
                }
                else if (!this.holder) {
                    currentBusinessLand = this;
                    businessContainerBuyLandBtn.textContent = `购买土地(${this.money}元)`
                    businessContainerBuyLandBtn.hidden = false;
                    businessContainer.setAttribute('style', 'display:flex')
                }
                else if (this.holder === player) {
                    nextDicePlayer()
                }
                else if (!this.mortgaged) {
                    let level = mapFunctionList[7].holder === mapFunctionList[21].holder ? 1 : 0
                    let toll = this.toll[level]
                    player.money -= toll;
                    this.holder.money += toll
                    log(`玩家${player.name}停留${this.name} 给玩家${this.holder.name} 支付过路费${toll}元`)
                    nextDicePlayer()
                }
                else {
                    nextDicePlayer()
                }
            }
            // 👮‍♀️欢迎回家~
            let goToPrison = function (player, score) {
                log(`玩家${player.name}入狱 暂停一回合`)
                player.moveScore += (mapElementList.length - player.moveScore % mapElementList.length + 9)
                let idx = player.knapsack.findIndex(item => item.name === '出狱许可证');
                if (idx > -1) {
                    log(`玩家${player.name} 使用出狱许可证 无需暂停`)
                    player.knapsack.splice(idx, 1)
                }
                else player.pause = true;
                let target = player.moveScore % mapElementList.length
                mapElementList[target].appendChild(player.chessPiece)
                mapFunctionList[target]['stop'](player, score)
            }
            // 机会地图事件
            let chanceMapFunction = new MapFunction({
                stop: (player, score) => {
                    let target = Randoms.getRandomInt(0, chanceFunctionList.length)
                    chanceFunctionList[target].run(player)
                }
            })
            // 命运地图事件
            let destinyMapFunction = new MapFunction({
                stop: (player, score) => {
                    let target = Randoms.getRandomInt(0, destinyFunctionList.length)
                    destinyFunctionList[target].run(player)
                }
            })
            // 地图事件列表
            mapFunctionList = [
                new MapFunction({
                    pass: (player, score) => {
                        log(`玩家${player.name}经过起点 奖励1000元`)
                        player.money += 1000;
                    },
                    stop: nextDicePlayer
                }),
                new MapLandFunction({
                    id: 1,
                    name: '中国',
                    money: 4000,
                    landSrc: './assets/monopoly/land4.jpg',
                    holder: null,
                    level: 0,
                    toll: [500, 2000, 5500, 11500],
                    upgrade: 2000,
                    stop: countryStop
                }),
                new MapLandFunction({
                    id: 2,
                    name: '泰国',
                    money: 1000,
                    landSrc: './assets/monopoly/land16.jpg',
                    holder: null,
                    level: 0,
                    toll: [100, 300, 900, 2000],
                    upgrade: 500,
                    stop: countryStop
                }),
                chanceMapFunction,
                new MapLandFunction({
                    id: 4,
                    name: '印尼',
                    money: 1600,
                    landSrc: './assets/monopoly/land7.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 600, 1800, 5000],
                    upgrade: 1000,
                    stop: countryStop
                }),
                new MapLandFunction({
                    id: 5,
                    name: '自来水厂',
                    money: 1200,
                    landSrc: './assets/monopoly/land14.jpg',
                    holder: null,
                    level: 0,
                    toll: [100, 300],
                    stop: hydropowerStop
                }),
                destinyMapFunction,
                new MapLandFunction({
                    id: 7,
                    name: '上海浦东国际机场',
                    money: 2000,
                    landSrc: './assets/monopoly/land18.jpg',
                    holder: null,
                    level: 0,
                    toll: [3000, 5000],
                    stop: airfieldStop
                }),
                new MapLandFunction({
                    id: 8,
                    name: '日本',
                    money: 2000,
                    landSrc: './assets/monopoly/land13.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 800, 2200, 6000],
                    upgrade: 1000,
                    stop: countryStop
                }),
                new MapFunction({
                    stop: nextDicePlayer
                }),
                new MapLandFunction({
                    id: 10,
                    name: '西班牙',
                    money: 2200,
                    landSrc: './assets/monopoly/land10.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 900, 2500, 7000],
                    upgrade: 1500,
                    stop: countryStop
                }),
                chanceMapFunction,
                new MapLandFunction({
                    id: 12,
                    name: '巴西',
                    money: 2400,
                    landSrc: './assets/monopoly/land12.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 1000, 3000, 7500],
                    upgrade: 1500,
                    stop: countryStop
                }),
                new MapFunction({
                    stop: (player, score) => {
                        log(`玩家${player.name}需要缴纳700元所得税`)
                        player.money -= 700;
                        nextDicePlayer()
                    }
                }),
                new MapLandFunction({
                    id: 14,
                    name: '加拿大',
                    money: 2600,
                    landSrc: './assets/monopoly/land6.jpg',
                    holder: null,
                    level: 0,
                    toll: [300, 1100, 3300, 8000],
                    upgrade: 1500,
                    stop: countryStop
                }),
                new MapFunction({
                    stop: (player, score) => {
                        log(`玩家${player.name}停留免费停车场 暂停一回合`)
                        player.pause = true;
                        nextDicePlayer()
                    }
                }),
                new MapLandFunction({
                    id: 16,
                    name: '土耳其',
                    money: 2200,
                    landSrc: './assets/monopoly/land3.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 900, 2500, 7000],
                    upgrade: 1500,
                    stop: countryStop
                }),
                new MapLandFunction({
                    id: 17,
                    name: '美国',
                    money: 2400,
                    landSrc: './assets/monopoly/land8.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 1000, 3000, 7500],
                    upgrade: 1500,
                    stop: countryStop
                }),
                destinyMapFunction,
                new MapLandFunction({
                    id: 19,
                    name: '英国',
                    money: 3000,
                    landSrc: './assets/monopoly/land9.jpg',
                    holder: null,
                    level: 0,
                    toll: [300, 1300, 3900, 9000],
                    upgrade: 2000,
                    stop: countryStop,
                }),
                new MapLandFunction({
                    id: 20,
                    name: '德国',
                    money: 3600,
                    landSrc: './assets/monopoly/land17.jpg',
                    holder: null,
                    level: 0,
                    toll: [400, 1800, 5000, 11000],
                    upgrade: 2000,
                    stop: countryStop
                }),
                new MapLandFunction({
                    id: 21,
                    name: '伦敦希思罗国际机场',
                    money: 2000,
                    landSrc: './assets/monopoly/land5.jpg',
                    holder: null,
                    level: 0,
                    toll: [3000, 5000],
                    stop: airfieldStop
                }),
                chanceMapFunction,
                new MapFunction({
                    stop: (player, score) => {
                        log(`玩家${player.name}需要缴纳500元签证费`)
                        player.money -= 500;
                        nextDicePlayer()
                    }
                }),
                new MapFunction({
                    stop: goToPrison
                }),
                new MapLandFunction({
                    id: 25,
                    name: '俄罗斯',
                    money: 3200,
                    landSrc: './assets/monopoly/land11.jpg',
                    holder: null,
                    level: 0,
                    toll: [300, 1500, 4500, 10000],
                    upgrade: 2000,
                    stop: countryStop
                }),
                destinyMapFunction,
                new MapLandFunction({
                    id: 27,
                    name: '法国',
                    money: 2200,
                    landSrc: './assets/monopoly/land15.jpg',
                    holder: null,
                    level: 0,
                    toll: [200, 900, 2500, 7000],
                    upgrade: 1500,
                    stop: countryStop
                }),
                new MapLandFunction({
                    id: 28,
                    name: '电力公司',
                    money: 1200,
                    landSrc: './assets/monopoly/land2.jpg',
                    holder: null,
                    level: 0,
                    toll: [100, 300],
                    stop: hydropowerStop
                }),
                new MapLandFunction({
                    id: 29,
                    name: '印度',
                    money: 1000,
                    landSrc: './assets/monopoly/land1.jpg',
                    holder: null,
                    level: 0,
                    toll: [100, 300, 900, 2700],
                    upgrade: 500,
                    stop: countryStop
                })
            ]
            // 命运选择
            let destinySelect = commentarySeat.querySelector('.destiny-select')
            let selectChance = destinySelect.querySelector('.select-btn.chance')
            let selectDestiny = destinySelect.querySelector('.select-btn.destiny')
            selectChance.addEventListener('click', function () {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                chanceMapFunction.stop(currentPlayer)
                destinySelect.hidden = true;
            })
            selectDestiny.addEventListener('click', function () {
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                destinyMapFunction.stop(currentPlayer)
                destinySelect.hidden = true;
            })

            // 暂停玩家选择
            let pauseUserSelect = commentarySeat.querySelector('.pause-user-select')
            function pauseUserSelectOpen() {
                pauseUserSelect.hidden = false;
                pauseUserSelect.innerHTML = ''
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                playerInfoList.filter(player => !player.isBankruptcy).forEach((player => {
                    let info = document.createElement('div')
                    info.classList.add('select-btn')
                    let avatar = document.createElement('img')
                    avatar.src = player.avater
                    let name = document.createElement('div')
                    name.textContent = player.name
                    info.appendChild(avatar)
                    info.appendChild(name)
                    pauseUserSelect.appendChild(info)

                    info.addEventListener('click', function () {
                        log(`玩家${currentPlayer.name} 指定 玩家${player.name} 暂停一回合`)
                        player.pause = true;
                        pauseUserSelect.hidden = true;
                        nextDicePlayer()
                    })
                }))
            }

            // 个人
            let moneyResultFunc = function (player) {
                log(`${player.name} ${this.info}`)
                player.money += this.award;
                nextDicePlayer()
            }
            // 群体
            let moneyAndOtherPlayersResultFunc = function (player) {
                log(`${player.name} ${this.info}`)
                let other = playerInfoList.filter(p => p != player && !p.isBankruptcy)
                player.money += other.length * this.award;
                other.map(p => p.money -= this.award)
                nextDicePlayer()
            }
            // 机会事件列表
            chanceFunctionList = [
                new ChanceFunction({
                    info: '到泰国按摩学院 学习正统泰式按摩 付学费500元',
                    award: -500,
                    resultSrc: './assets/monopoly/chance1.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '在纽约时代广场 扮演街头艺 打赏500元',
                    award: 500,
                    resultSrc: './assets/monopoly/chance2.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '破坏英国大英博物馆 珍稀艺术品 罚款1000元',
                    award: -1000,
                    resultSrc: './assets/monopoly/chance3.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '成立爱心慈善基金会 帮助弱势群体 奖励1200元',
                    award: 1200,
                    resultSrc: './assets/monopoly/chance4.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '获聘为法国蓝带厨艺学院 首席教师 奖励金800元',
                    award: 800,
                    resultSrc: './assets/monopoly/chance5.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '成功登上世界最高峰 「珠穆朗玛峰」 每位玩家给你奖励金300元',
                    award: 300,
                    resultSrc: './assets/monopoly/chance6.jpg',
                    resultFunc: moneyAndOtherPlayersResultFunc
                }),
                new ChanceFunction({
                    info: '参加巴西狂欢节游行 人潮众多，遭遇扒手集团 损失700元',
                    award: -700,
                    resultSrc: './assets/monopoly/chance7.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '考古新发现 在埃及挖掘出稀世珍宝 奖金800元',
                    award: 800,
                    resultSrc: './assets/monopoly/chance8.jpg',
                    resultFunc: moneyResultFunc
                }),
                new ChanceFunction({
                    info: '参加北京故宫志愿者服务队，精神可嘉 全体玩家为你鼓掌10秒钟',
                    resultSrc: './assets/monopoly/chance9.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        nextDicePlayer()
                    }
                }),
                new ChanceFunction({
                    info: '招待朋友去看 世界杯足球赛 付给每位玩家200元',
                    award: -200,
                    resultSrc: './assets/monopoly/chance10.jpg',
                    resultFunc: moneyAndOtherPlayersResultFunc
                }),
                new ChanceFunction({
                    name: '免费升级卡',
                    info: '投资印尼巴厘岛度假村 可在自己土地上任选一处免费升级一栋房屋',
                    resultSrc: './assets/monopoly/chance11.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        player.knapsack.push(this)
                        nextDicePlayer()
                    }
                }),
                new ChanceFunction({
                    info: '搭乘豪华游轮环游世界 费用900元',
                    award: -900,
                    resultSrc: './assets/monopoly/chance12.jpg',
                    resultFunc: moneyResultFunc
                }),
            ]
            // 命运事件列表
            destinyFunctionList = [
                new DestinyFunction({
                    info: '眼光精准 投资股票获利 得300元',
                    award: 300,
                    resultSrc: './assets/monopoly/destiny1.jpg',
                    resultFunc: moneyResultFunc
                }),
                new DestinyFunction({
                    info: '在非洲肯尼亚野生动物园区 乱喂食动物 罚款800元',
                    award: -800,
                    resultSrc: './assets/monopoly/destiny2.jpg',
                    resultFunc: moneyResultFunc
                }),
                new DestinyFunction({
                    info: '参加抽奖大赛 可任意选择再翻一张命运卡或机会卡',
                    resultSrc: './assets/monopoly/destiny3.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        this.container.hidden = true;
                        destinySelect.hidden = false;
                    }
                }),
                new DestinyFunction({
                    info: '入选国家队 代表参加奥运会比赛 请每位玩家赞美你1个优点',
                    resultSrc: './assets/monopoly/destiny4.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        nextDicePlayer()
                    }
                }),
                new DestinyFunction({
                    name: '出狱许可证',
                    info: '获得出狱许可证',
                    resultSrc: './assets/monopoly/destiny5.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        player.knapsack.push(this)
                        nextDicePlayer()
                    }
                }),
                new DestinyFunction({
                    info: '投稿上海外滩夜景照片 获得世界摄影大赛冠军 奖金1000元',
                    award: 1000,
                    resultSrc: './assets/monopoly/destiny6.jpg',
                    resultFunc: moneyResultFunc
                }),
                new DestinyFunction({
                    info: '走路玩手机 不幸被汽车撞断腿 下回合暂停一次',
                    resultSrc: './assets/monopoly/destiny7.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        player.pause = true;
                        nextDicePlayer()
                    }
                }),
                new DestinyFunction({
                    info: '走私毒品 立刻坐牢 若经过起点“由此去” 不得领取1000元',
                    resultSrc: './assets/monopoly/destiny8.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        goToPrison(player, 1)
                    }
                }),
                new DestinyFunction({
                    info: '搭乘热气球 游览澳洲黄金海岸 可重新掷骰再玩一次',
                    resultSrc: './assets/monopoly/destiny9.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                    }
                }),
                new DestinyFunction({
                    info: '在冰岛看北极光 防寒设备不足冻伤 可指定任一玩家 下回合暂停一次',
                    resultSrc: './assets/monopoly/destiny10.jpg',
                    resultFunc: function (player) {
                        log(`${player.name} ${this.info}`)
                        this.container.hidden = false;
                        pauseUserSelectOpen()
                    }
                }),
                new DestinyFunction({
                    info: '受邀参加戛纳电影节 开幕典礼 花置装费600元',
                    award: -600,
                    resultSrc: './assets/monopoly/destiny11.jpg',
                    resultFunc: moneyResultFunc
                }),

                new DestinyFunction({
                    info: '不幸遭遇地震 房屋倒塌 付修缮费1200元',
                    award: -1200,
                    resultSrc: './assets/monopoly/destiny12.jpg',
                    resultFunc: moneyResultFunc
                }),
            ]
            // 规则按钮点击事件
            ruleBtn.addEventListener("click", () => {
                gameStart.hidden = true;
                gameRule.hidden = false
            })
            // 规则关闭按钮点击事件
            ruleCloseBtn.addEventListener('click', () => {
                gameStart.hidden = false;
                gameRule.hidden = true
            })
            // 选择玩家按钮点击事件
            selectPlayers.forEach(player => {
                player.addEventListener('click', function () {
                    if (player.classList.contains('active')) {
                        // 当人数小于两个不移除标签
                        if (document.querySelectorAll('.players .player.active').length > 2) {
                            player.classList.remove('active')
                        }
                    }
                    else {
                        player.classList.add('active')
                    }
                })
            })
            // 开始游戏点击事件
            startBtn.addEventListener("click", () => {
                mapMask.setAttribute('style', 'display:none')
                commentarySeat.setAttribute('style', 'display:flex')
                let selected = document.querySelectorAll('.players .player.active')
                let playerList = commentarySeat.querySelector('.player-list')
                selected.forEach(function (player, index) {
                    let chessPiece = document.createElement('div')
                    let information = document.createElement('div')
                    let color = player.querySelector('.color').textContent;
                    let src = player.querySelector('img').src
                    let money = config.money
                    let isBankruptcy = false
                    chessPiece.classList.add('player')
                    information.classList.add('player')

                    chessPiece.setAttribute('style', `background-image:url(${src});--border-color:${color}`)
                    // 新建头像
                    let infoAvatar = document.createElement('img')
                    infoAvatar.setAttribute("src", src)
                    infoAvatar.classList.add('avatar')
                    infoAvatar.setAttribute('style', `--border-color:${color}`)
                    if (dicePlayerIndex === index) infoAvatar.classList.add('active')
                    // 新建资金栏
                    let fund = document.createElement('div')
                    fund.classList.add('fund')
                    fund.textContent = money
                    // 新建物品栏
                    let inventory = document.createElement('div')
                    inventory.classList.add('inventory')
                    // 新建已破产
                    let bankruptcy = document.createElement('div')
                    bankruptcy.classList.add('bankruptcy')
                    bankruptcy.textContent = '已破产'
                    bankruptcy.hidden = !isBankruptcy

                    information.appendChild(infoAvatar)
                    information.appendChild(fund)
                    information.appendChild(inventory)
                    information.appendChild(bankruptcy)
                    playerList.appendChild(information)
                    // 玩家棋子初始位置
                    mapElementList[0].appendChild(chessPiece)
                    // 玩家信息
                    const playerInfo = {
                        avater: src,
                        name: player.querySelector('.name').textContent,
                        color,
                        moveScore: 0,
                        pause: false,
                        money,
                        knapsack: null,
                        isBankruptcy,
                        information,
                        fund,
                        chessPiece,
                        inventory,
                        bankruptcy,
                    }
                    playerInfo.knapsack = new Knapsack(playerInfo)
                    // 绑定金钱
                    Object.defineProperty(playerInfo, 'money', {
                        get() {
                            return money
                        },
                        set(val) {
                            money = val
                            fund.textContent = money
                        }
                    })
                    // 绑定是否破产
                    Object.defineProperty(playerInfo, 'isBankruptcy', {
                        get() {
                            return isBankruptcy
                        },
                        set(val) {
                            isBankruptcy = val
                            bankruptcy.hidden = !val
                        }
                    })

                    playerInfoList.push(playerInfo)
                })

                log('游戏开始')
                log(`请玩家${playerInfoList[dicePlayerIndex].name}开始掷色子`)
            })
            // 🎲
            dice.addEventListener('click', diceClick)
            // 重新开始
            document.querySelector('.game-over-container .reset-btn').addEventListener('click', () => {
                location.reload()
            })

            // 银行
            let bankContainer = document.querySelector('.bank-container')
            let mortgageCancelBtn = bankContainer.querySelector('.cancel-btn')

            // 取消
            mortgageCancelBtn.addEventListener('click', () => {
                bankContainer.hidden = true;
                let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
                landConfiscate(currentPlayer)
                nextDicePlayer()
            })

            log('游戏初始化完成')
        }

        // 玩家移动
        async function moving(player, score) {
            let current = player.moveScore % mapElementList.length
            let wait = () => new Promise((resolve) => {
                setTimeout(resolve, 100)
            })
            for (let i = 0; i < score; i++) {
                await wait();
                player.moveScore++;
                let target = player.moveScore % mapElementList.length
                mapElementList[target].appendChild(player.chessPiece)
                let funcName = i === score - 1 ? 'stop' : 'pass';
                mapFunctionList[target][funcName](player, score)
            }
        }

        // 骰子🎲
        async function diceClick() {
            if (diceTurn) return;
            diceTurn = true
            let target = Randoms.getRandomInt(1, 7);
            let length = target // 18 + target;
            let diceChildren = dice.children
            let wait = () => new Promise((resolve) => {
                setTimeout(resolve, 100)
            })
            for (let i = 0; i < length; i++) {
                await wait();
                dice.querySelector('img:not([hidden])').hidden = true
                diceChildren.item(i % 6).hidden = false
            }
            let playerInfo = playerInfoList[dicePlayerIndex % playerInfoList.length]
            log(`玩家${playerInfo.name}掷色子数为${target}`)
            await moving(playerInfo, target)
            diceTurn = false
        }

        // 下一个摇骰子人
        function nextDicePlayer() {
            checkGameOver();
            // 处理当前人
            let currentPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
            if (currentPlayer.money < 0 && !currentPlayer.isBankruptcy) {
                startMortgage(currentPlayer)
                return
            }
            dicePlayerIndex++;
            let nextPlayer = playerInfoList[dicePlayerIndex % playerInfoList.length];
            if (nextPlayer.pause) {
                nextPlayer.pause = false;
                return nextDicePlayer()
            }
            // 破产
            if (nextPlayer.isBankruptcy) {
                return nextDicePlayer()
            }
            commentarySeat.querySelector('.player-list .avatar.active').classList.remove('active')
            nextPlayer.information.querySelector('.avatar').classList.add('active')
            log(`请玩家${nextPlayer.name}开始掷色子`)
        }

        // 打印日志
        function log(str) {
            let element = document.createElement('div')
            element.textContent = str
            logList.appendChild(element)
            logList.scrollTo({ top: 100000000 })
        }

        // 开始抵押
        function startMortgage(player) {
            console.log(player);
            // 土地可抵押列表
            let bankContainer = document.querySelector('.bank-container')
            bankContainer.hidden = false;
            let landList = bankContainer.querySelector('.land-list')
            landList.innerHTML = ``
            let playerLandList = mapFunctionList.filter(map => map instanceof MapLandFunction && map.holder === player);
            let landMonery = playerLandList.filter(map => !map.mortgaged).reduce((total, map) => {
                let levelMoney = map.level * map.upgrade
                let totalMoney = map.money + (isNaN(levelMoney) ? 0 : levelMoney)
                total += totalMoney;
                return total;
            }, 0)
            // 破产
            if (player.money + landMonery < 0) {
                player.isBankruptcy = true;
                bankContainer.hidden = true;
                landConfiscate(player)
                nextDicePlayer()
            }
            else {
                playerLandList.forEach(map => {
                    let landItem = document.createElement('div')
                    let levelMoney = map.level * map.upgrade
                    let totalMoney = map.money + (isNaN(levelMoney) ? 0 : levelMoney)
                    landItem.innerHTML = `
                            <div class="info">
                                <div class="name">${map.name}</div>
                                <div class="money">${totalMoney}元</div>
                            </div>
                            <div class="mortgage-btn" ${map.mortgaged ? "hidden" : ""}>抵押</div>
                            <div class="mortgaged" ${!map.mortgaged ? "hidden" : ""}>已抵押</div>
                        `
                    landItem.classList.add('land-item')
                    let mortgageBtn = landItem.querySelector('.mortgage-btn')
                    let mortgaged = landItem.querySelector('.mortgaged')
                    mortgageBtn.onclick = function () {
                        map.mortgaged = true;
                        mortgageBtn.hidden = true;
                        mortgaged.hidden = false;
                        console.log(player);
                        player.money += totalMoney

                        if (player.money >= 0) {
                            bankContainer.hidden = true;
                            nextDicePlayer()
                        }
                    }
                    landList.appendChild(landItem)
                })
            }
        }

        // 土地充公
        function landConfiscate(player) {
            mapFunctionList.forEach(map => {
                if (map instanceof MapLandFunction && map.holder === player) {
                    map.mortgaged = false;
                    map.level = 0;
                    map.holder = null;
                }
            })
        }

        // 检查
        function checkGameOver() {
            let survivors = playerInfoList.filter(player => player.isBankruptcy === false)
            if (survivors.length === 1) {
                let gameOver = document.querySelector('.game-over-container')
                gameOver.hidden = false;
                gameOver.querySelector('.h1').textContent = `恭喜${survivors[0].name}获得了游戏的胜利✌`
            }
        }
        // 执行初始化
        init();
    </script>
</body>

</html>